package com.demo.service;

import com.alibaba.fastjson.JSON;
import com.demo.config.DrivingTestHandlerConfig;
import com.demo.handler.AbstractDrivingTestHandler;
import com.demo.model.Result;
import com.demo.model.DrivingTest;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.util.Map;
import java.util.Objects;

@Component
@Slf4j
public class DrivingTestService {

    /**
     * 使用Spring注入:所有继承了AbstractJudgeHandler抽象类的Spring Bean都会注入进来。Map的Key对应Bean的name,Value是name对应相应的Bean
     */
    @Resource
    private Map<String, AbstractDrivingTestHandler> handlerMap;


    /**
     * 责任链处理开始
     *
     * @param param
     * @return
     */
    public Result drivingTestChain(DrivingTest param) {

        //获取处理器配置：通常配置使用统一配置中心存储，支持动态变更
        DrivingTestHandlerConfig handlerConfig = this.getHandlerConfigFile();

        //获取处理器
        AbstractDrivingTestHandler handler = this.getHandler(handlerConfig);

        //责任链：执行处理器链路
        Result executeChainResult = this.executeChain(handler, param);
        if (!executeChainResult.isSuccess()) {
            return executeChainResult;
        }
        //处理器链路全部成功
        return new Result(200,"恭喜您通过驾照考试，请 7 天内领取驾照","");
    }


    /**
     * 执行链路
     *
     * @param handler 处理器
     * @param param   商品参数
     * @return
     */
    public Result executeChain(AbstractDrivingTestHandler handler, DrivingTest param) {
        //执行处理器
        Result handlerResult = handler.handle(param);
        if (!handlerResult.isSuccess()) {
            return handlerResult;
        }
        return Result.success();
    }

    /**
     * 获取处理器配置：通常配置使用统一配置中心存储，支持动态变更
     * subject1Handler 代表科目一
     * subject2Handler 代表科目二
     * subject3Handler 代表科目三
     * subject4Handler 代表科目四
     *
     * {
     *     "handler":"subject1Handler",
     *     "down":false,
     *     "next":{
     *         "handler":"subject2Handler",
     *         "next":{
     *             "handler":"subject3Handler",
     *             "next":{
     *                 "handler":"subject4Handler",
     *                 "next":null,
     *                 "down":false
     *             },
     *             "down":false
     *         },
     *         "down":false
     *     }
     * }
     *
     *
     * @return
     */
    private DrivingTestHandlerConfig getHandlerConfigFile() {
        //模拟配置中心存储的配置
        String configJson = "{\"handler\":\"subject1Handler\",\"down\":false,\"next\":{\"handler\":\"subject2Handler\",\"next\":{\"handler\":\"subject3Handler\",\"next\":{\"handler\":\"subject4Handler\",\"next\":null,\"down\":false},\"down\":false},\"down\":false}}";
        //转成Config对象，含有下一节点的handler
        DrivingTestHandlerConfig handlerConfig = JSON.parseObject(configJson, DrivingTestHandlerConfig.class);
        return handlerConfig;
    }

    /**
     * 获取相应科目的处理器
     * 科目一  --> 科目二  --> 科目三 --> 科目四
     *
     * @param config
     * @return
     */
    private AbstractDrivingTestHandler getHandler(DrivingTestHandlerConfig config) {
        //配置检查：没有配置处理器链路，则不执行校验逻辑
        if (Objects.isNull(config)) {
            return null;
        }
        //配置错误，则返回空
        String handler = config.getHandler();
        if (StringUtils.isBlank(handler)) {
            return null;
        }
        //配置了不存在的处理器，则返回空
        AbstractDrivingTestHandler abstractDrivingTestHandler = handlerMap.get(config.getHandler());
        if (Objects.isNull(abstractDrivingTestHandler)) {
            return null;
        }
        // 如果节点配置下线则不进行校验
        if(config.getDown()){
            return null;
        }

        //处理器设置配置Config
        abstractDrivingTestHandler.setConfig(config);
        //递归设置链路处理器
        abstractDrivingTestHandler.setNextHandler(this.getHandler(config.getNext()));
        return abstractDrivingTestHandler;
    }


}
